% !TEX root = TMV_Documentation.tex

\section{Diagonal matrices}
\index{DiagMatrix}
\label{DiagMatrix}

The \tt{DiagMatrix} class is our diagonal matrix class.  
A diagonal matrix is only non-zero
along the main diagonal of the matrix.  

The class \tt{DiagMatrix} inherits from \tt{GenDiagMatrix},
which in turn inherits from \tt{BaseMatrix}.
The various views and composite classes described below
also inherit from \tt{GenDiagMatrix}.
\index{DiagMatrix!DiagMatrixView}
\index{DiagMatrix!ConstDiagMatrixView}
\index{DiagMatrix!GenDiagMatrix}
\index{DiagMatrix!DiagMatrixComposite}
\index{BaseMatrix}

Most functions and methods for \tt{DiagMatrix} work the same
as they do for \tt{Matrix}.
In these cases, we will just list the functions
that are allowed with the
effect understood to be the same as for a regular \tt{Matrix}.  Of course, there are 
almost always algorithmic speed-ups, which the code will use to take advantage of the 
diagonal structure.
Whenever there is a difference in how a function works,
we will explain the difference.

\subsection{Constructors}
\index{DiagMatrix!Constructors}
\label{DiagMatrix_Constructors}

As usual, the optional \tt{index} template argument specifies which indexing
style to use.

\begin{itemize}
\item 
\begin{tmvcode}
tmv::DiagMatrix<T,index> d(size_t n)
\end{tmvcode}
Makes an \tt{n} $\times$ \tt{n} \tt{DiagMatrix} with \underline{uninitialized} values.
If debugging is turned on (i.e. not turned off
with \tt{-DNDEBUG} or \tt{-DTMVNDEBUG}), then the values along the diagonal are in fact initialized to 888. 

\item
\begin{tmvcode}
tmv::DiagMatrix<T,index> d(size_t n, T x)
\end{tmvcode}
Makes an \tt{n} $\times$ \tt{n} \tt{DiagMatrix} with all values along the diagonal equal to \tt{x}.

\item
\begin{tmvcode}
tmv::DiagMatrix<T,index> m(size_t n, const T* vv)
tmv::DiagMatrix<T,index> m(const std::vector<T>& vv)
\end{tmvcode}
Makes a \tt{DiagMatrix} which copies the elements of \tt{vv}.

\item
\begin{tmvcode}
tmv::DiagMatrix<T,index> d(const GenVector<T>& v)
\end{tmvcode}
Makes a \tt{DiagMatrix} with \tt{v} as the diagonal.

\item 
\begin{tmvcode}
tmv::DiagMatrix<T,index> d(const GenMatrix<T>& m)
\end{tmvcode}
Makes a \tt{DiagMatrix} with the diagonal of \tt{m} as the diagonal.

\item
\begin{tmvcode}
tmv::DiagMatrix<T,index> d1(const GenDiagMatrix<T2>& d2)
d1 = d2
\end{tmvcode}
Copy the \tt{DiagMatrix d2}, which may be of any type \tt{T2} so long
as values of type \tt{T2} are convertible into type \tt{T}.
The assignment operator has the same flexibility.

\item
\begin{tmvcode}
tmv::DiagMatrixView<T,index> d = 
      DiagMatrixViewOf(VectorView<T,index> v)
tmv::ConstDiagMatrixView<T,index> d = 
      DiagMatrixViewOf(ConstVectorView<T,index> v)
\end{tmvcode}
\index{Vector!Functions of!DiagMatrixViewOf}
\index{Vector!View as a diagonal matrix}
Makes a \tt{DiagMatrixView} whose diagonal is \tt{v}.

\item
\begin{tmvcode}
tmv::DiagMatrixView<T,index> d = 
      tmv::DiagMatrixViewOf(T* vv, size_t n)
tmv::ConstDiagMatrixView<T,index> d = 
      tmv::DiagMatrixViewOf(const T* vv, size_t n)
\end{tmvcode}
\index{DiagMatrix!View of raw memory}
Make a \tt{DiagMatrixView} whose diagonal consists of the actual memory elements \tt{vv}.

\end{itemize}


\subsection{Access}
\index{DiagMatrix!Access methods}
\label{DiagMatrix_Access}

\begin{tmvcode}
d.resize(size_t newsize)
\end{tmvcode}
\index{DiagMatrix!Methods!resize}

\begin{tmvcode}
d.nrows() = d.ncols() = d.colsize() = d.rowsize() = d.size()
d(i,j)
d(i) = d(i,i)
\end{tmvcode}
\index{DiagMatrix!Methods!nrows}
\index{DiagMatrix!Methods!ncols}
\index{DiagMatrix!Methods!rowsize}
\index{DiagMatrix!Methods!colsize}
\index{DiagMatrix!Methods!size}
\index{DiagMatrix!Methods!operator()}
For the mutable \tt{d(i,j)} version, 
\tt{i} must equal \tt{j}.
If \tt{d} is not mutable, then \tt{d(i,j)} with \tt{i}$\neq$\tt{j} returns the 
value 0.

\begin{tmvcode}
d.diag()
\end{tmvcode}
\index{DiagMatrix!Methods!diag}

\begin{tmvcode}
d.subDiagMatrix(int i1, int i2, int istep = 1)
\end{tmvcode}
This is equivalent to \tt{DiagMatrixViewOf(d.diag().subVector(i1,i2,istep))}.
\begin{tmvcode}
d.transpose() = d.view()
d.conjugate() = d.adjoint()
d.cview()
d.fview()
d.realPart()
d.imagPart()
\end{tmvcode}
\index{DiagMatrix!Methods!subDiagMatrix}
\index{DiagMatrix!Methods!transpose}
\index{DiagMatrix!Methods!conjugate}
\index{DiagMatrix!Methods!adjoint}
\index{DiagMatrix!Methods!view}
\index{DiagMatrix!Methods!cView}
\index{DiagMatrix!Methods!fView}
\index{DiagMatrix!Methods!realPart}
\index{DiagMatrix!Methods!imagPart}

\subsection{Functions}
\index{DiagMatrix!Functions of}
\label{DiagMatrix_Functions}

\begin{tmvcode}
RT d.norm1() = Norm1(d)
RT d.norm2() = Norm2(d) = d.doNorm2()
RT d.normInf() = NormInf(d)
RT d.maxAbsElement() = MaxAbsElement(d)
\end{tmvcode}
\index{DiagMatrix!Functions of!Norm1}
\index{DiagMatrix!Functions of!Norm2}
\index{DiagMatrix!Functions of!NormInf}
\index{DiagMatrix!Functions of!MaxAbsElement}
\index{DiagMatrix!Methods!norm1}
\index{DiagMatrix!Methods!norm2}
\index{DiagMatrix!Methods!doNorm2}
\index{DiagMatrix!Methods!normInf}
\index{DiagMatrix!Methods!maxAbsElement}
(Actually for a diagonal matrix, all of the above norms are equal.)
\begin{tmvcode}
RT d.maxAbs2Element() = MaxAbs2Element(d)
RT d.normF() = NormF(d) = d.norm() = Norm(d)
RT d.normSq() = NormSq(d)
RT d.normSq(RT scale)
T d.trace() = Trace(d)
T d.sumElements() = SumElements(d)
RT d.sumAbsElements() = SumAbsElements(d)
RT d.sumAbs2Elements() = SumAbs2Elements(d)
T d.det() = Det(d)
RT d.logDet(T* sign=0) = LogDet(d)
bool d.isSingular()
RT d.condition()
RT d.doCondition()
dinv = d.inverse() = Inverse(d)
d.makeInverse(Matrix<T>& minv)
d.makeInverse(DiagMatrix<T>& dinv)
d.makeInverseATA(Matrix<T>& cov)
d.makeInverseATA(DiagMatrix<T>& cov)
\end{tmvcode}
\index{DiagMatrix!Functions of!MaxAbs2Element}
\index{DiagMatrix!Functions of!Norm}
\index{DiagMatrix!Functions of!NormF}
\index{DiagMatrix!Functions of!NormSq}
\index{DiagMatrix!Functions of!Trace}
\index{DiagMatrix!Functions of!SumElements}
\index{DiagMatrix!Functions of!SumAbsElements}
\index{DiagMatrix!Functions of!SumAbs2Elements}
\index{DiagMatrix!Functions of!Det}
\index{DiagMatrix!Functions of!LogDet}
\index{DiagMatrix!Functions of!Inverse}
\index{DiagMatrix!Methods!maxAbs2Element}
\index{DiagMatrix!Methods!norm}
\index{DiagMatrix!Methods!normF}
\index{DiagMatrix!Methods!normSq}
\index{DiagMatrix!Methods!trace}
\index{DiagMatrix!Methods!sumElements}
\index{DiagMatrix!Methods!sumAbsElements}
\index{DiagMatrix!Methods!sumAbs2Elements}
\index{DiagMatrix!Methods!det}
\index{DiagMatrix!Methods!logDet}
\index{DiagMatrix!Methods!isSingular}
\index{DiagMatrix!Methods!condition}
\index{DiagMatrix!Methods!doCondition}
\index{DiagMatrix!Methods!inverse}
\index{DiagMatrix!Methods!makeInverse}
\index{DiagMatrix!Methods!makeInverseATA}
Since the inverse of a \tt{DiagMatrix} is a \tt{DiagMatrix},
we also provide a version of the \tt{makeInverse} syntax, which allows dinv
to be a \tt{DiagMatrix}.  (Likewise for \tt{makeInverseATA}.)  The same option is 
available with the operator version: \tt{dinv = d.inverse()}.

\begin{tmvcode}
d.setZero()
d.setAllTo(T x)
d.addToAll(T x)
d.clip(RT thresh)
d.setToIdentity(T x = 1)
d.conjugateSelf()
d.transposeSelf() // null operation
d.invertSelf()
Swap(d1,d2)
\end{tmvcode}
\index{DiagMatrix!Methods!setZero}
\index{DiagMatrix!Methods!setAllTo}
\index{DiagMatrix!Methods!addToAll}
\index{DiagMatrix!Methods!clip}
\index{DiagMatrix!Methods!setToIdentity}
\index{DiagMatrix!Methods!conjugateSelf}
\index{DiagMatrix!Methods!transposeSelf}
\index{DiagMatrix!Methods!invertSelf}
\index{DiagMatrix!Functions of!Swap}
There is one new method here for \tt{DiagMatrix}: The method \tt{invertSelf}  calculates $d^{-1}$ in place.  
It is equivalent to \tt{d = d.inverse()} and, like the other division operations, is invalid for \tt{T = int} or \tt{complex<int>}.
\vspace{12pt}

\subsection{Arithmetic}
\index{DiagMatrix!Arithmetic}
\label{DiagMatrix_Arithmetic}

In addition to \tt{x}, \tt{v}, and \tt{m} from before, we now add \tt{d} for a \tt{DiagMatrix}.

\begin{tmvcode}
d2 = -d1
d2 = x * d1
d2 = d1 [*/] x
d3 = d1 [+-] d2
m2 = m1 [+-] d
m2 = d [+-] m1
d [*/]= x
d2 [+-]= d1
m [+-]= d
v2 = d * v1
v2 = v1 * d
v *= d
d3 = d1 * d2
m2 = d * m1
m2 = m1 * d
d2 *= d1
m *= d
d2 = d1 [+-] x
d2 = x [+-] d1
d [+-]= x
d = x
\end{tmvcode}

\subsection{Division}
\index{DiagMatrix!Arithmetic!division}
\label{DiagMatrix_Division}

The division operations are:
\begin{tmvcode}
v2 = v1 [/%] d
m2 = m1 [/%] d
m2 = d [/%] m1
d3 = d1 [/%] d2
d2 = x [/%] d1
v [/%]= d
d2 [/%]= d1
m [/%]= d
\end{tmvcode}

There is only one allowed \tt{DivType} for a \tt{DiagMatrix}: \tt{LU}. 
And, since it is also the default behavior,
there is no reason to ever use this function.  Furthermore, since a \tt{DiagMatrix}
is already a $U$ matrix, the decomposition requires no work at all.
Hence, it is always done in place; no extra storage is needed, and 
the methods \tt{m.divideInPlace()}, \tt{m.saveDiv()}, etc. are irrelevant.

If a \tt{DiagMatrix} is singular, you can find out with \tt{m.isSingular()},
but there is no direct way to use SVD for the division and skip any
divisions by 0.  If you want to do this, you should use \tt{BandMatrixViewOf(d)} to 
treat the \tt{DiagMatrix} as a \tt{BandMatrix}, which can use SVD.

\subsection{Input/Output}
\index{DiagMatrix!Input/output}
\label{DiagMatrix_IO}

The simplest output is the usual:
\begin{tmvcode}
os << d
\end{tmvcode}
where \tt{os} is any \tt{std::ostream}.
The output format is the same as for a \tt{Matrix}, including all the 0's.
(See \ref{Matrix_IO}.)


There is also a compact format:
\begin{tmvcode}
d.writeCompact(os)
\end{tmvcode}
\index{DiagMatrix!Methods!writeCompact}
which outputs in the format:
\begin{tmvcode}
D n ( d(0,0)  d(1,1)  d(2,2)  ...  d(n-1,n-1) )
\end{tmvcode}

The same (compact, that is) format can be read back in the usual two ways:
\begin{tmvcode}
tmv::DiagMatrix<T> d(n);
is >> d;
std::auto_ptr<tmv::DiagMatrix<T> > dptr;
is >> dptr;
\end{tmvcode}
where the first gives an error if \tt{d} is the wrong size and the second allocates
a new \tt{DiagMatrix} that is the correct size.

One can also write small values as 0 with
\begin{tmvcode}
m.write(std::ostream& os, RT thresh)
m.writeCompact(std::ostream& os, RT thresh)
\end{tmvcode}
\index{DiagMatrix!Methods!write}
\index{DiagMatrix!Methods!writeCompact}
